/*
	FieldDamage.cpp
	(c)2004 Palestar Inc, Richard Lyle
*/


#include "FieldDamage.h"
#include "GameContext.h"
#include "Resource.h"

//----------------------------------------------------------------------------

IMPLEMENT_FACTORY( FieldDamage, NounField );
REGISTER_FACTORY_KEY( FieldDamage, 4775406032264294020 );

BEGIN_PROPERTY_LIST( FieldDamage, NounField )
	ADD_TRANSMIT_UPDATE_PROPERTY( m_fLife );
	ADD_PROPERTY( m_nInflictDamage );
	ADD_PROPERTY( m_nInflictDamageType );
END_PROPERTY_LIST();

FieldDamage::FieldDamage() : m_fLife( 0.0f ), m_nInflictDamage( 1 ), m_nInflictDamageType( DAMAGE_ENERGY )
{}

//----------------------------------------------------------------------------

void FieldDamage::simulate( dword nTick )
{
	float fElapsed = TICK_DURATION_S * (nTick - tick());

	m_fLife -= fElapsed;
	if ( m_fLife < 0.0f )
		setLink( NULL );		// field life expended, unlink this field so it will be detached...

	// damage can only occur on the server side, so skip this on the client..
	if ( server() )
	{
		// inflict damage on all objects inside the pulse field.. except for the object we are linked!
		for(int i=0;i<m_InField.size();i++)
		{
			NounGame * pNoun = WidgetCast<NounGame>( m_InField[ i ] );
			if ( pNoun != NULL && pNoun != link() && pNoun->canDamage( m_nInflictDamageType ) )
			{
				Vector3 vDirection( worldPosition() - pNoun->worldPosition() );

				float fDistance = vDirection.magnitude();
				float fDamageRatio = 1.0f - (fDistance / m_fFieldRadius);
				if ( fDamageRatio < 0.0f )
					fDamageRatio = 0.0f;		// don't allow negative ratios

				int nInflict = (fDamageRatio * ((m_nInflictDamage * TICK_DURATION_S))) + 1;

				// send the damage verb
				gameContext()->pushDamage( pNoun, link(), nInflict, m_nInflictDamageType, 
					pNoun->worldFrame() * vDirection );
			}
		}
	}

	NounField::simulate( nTick );
}

//----------------------------------------------------------------------------

void FieldDamage::onEnterField( Noun * pNoun )
{}

void FieldDamage::onInsideField( Noun * pNoun )
{}

void FieldDamage::onLeaveField( Noun * pNoun )
{}

//----------------------------------------------------------------------------
//EOF
